package com.zhuqi.configuration;

import cn.hutool.core.thread.NamedThreadFactory;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author : ZhuQi
 * @version : 时间:2022/8/9 11:43 版本:
 * boot 线程池配置类
 */
@Configuration
@Data
@Slf4j
public class ExecutorConfiguration {

    private LinkedBlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>();

    private ThreadGroup threadGroup;

    @Autowired
    private PropertiesConfiguration configuration;

    /**
     * 创建 Spring boot 执行器
     *
     * @return ThreadPoolTaskExecutor
     */
    @Bean("taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(configuration.getCoreSize() - 1);
        executor.setMaxPoolSize(configuration.getCoreSize() - 1);
        executor.setQueueCapacity(5000);
        executor.setKeepAliveSeconds(5);
        executor.setThreadFactory(new NamedThreadFactory("async-thread", false));
        // 线程池对拒绝任务的处理策略
        // CallerRunsPolicy：由调用线程（提交任务的线程）处理该任务
        executor.setRejectedExecutionHandler(new ExecutionHandel());
        // 初始化
        executor.initialize();
        return executor;
    }

    /**
     * 自定义拒绝策略
     */
    class ExecutionHandel implements RejectedExecutionHandler {

        /**
         * 添加任务至阻塞队列
         */
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            log.warn("触发拒绝策略添加任务至阻塞队列,当前阻塞队列大小:{}", blockingQueue.size());
            blockingQueue.add(r);
        }
    }
}
